using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using WorkFlowCore.Authorization;
using WorkFlowCore.Common.Authorization.JWT;
using WorkFlowCore.Plugins;

namespace WorkFlowCore.Framework.Authorization
{
    [PluginDescription("参数：token-from=[headers,query] token解析来源，默认 headers")]
    [PluginDescription("参数：token-key=[ThirdpartAuthorization] token名，默认 ThirdpartAuthorization")]
    [PluginDescription("参数：token-to=[headers,query] token解析来源，默认 headers")]
    [PluginDescription("参数：to-token-key=[authorization] token名，默认 authorization")]
    [PluginDescription("参数：method=[post,get] 请求方式，默认 get")]
    [PluginDescription("参数：token-format=Bearer {token}")]
    [PluginDescription("参数：url=[url] 认证地址")]
    [PluginDescription("返回值：{IsValid:bool,是否认证通过,User:{Id:string 用户唯一标识,Name:string 用户名称,IsManager:bool是否是管理员},Claims:[{type:\"\",value:\"\"}] 额外的身份信息，可为空}")]
    public class DefaultCustomizationVerifyExtension : ICustomizationVerifyExtension
    {
        private ConfigureContext configureContext;
        public async Task Configure(ConfigureContext configureContext)
        {
            this.configureContext = configureContext;
        }

        public VerifyOutput Verify(VerifyInput input)
        {
#if DEBUG
            Console.WriteLine($"DefaultCustomizationVerifyExtension-Verify:{input.AppId}");
#endif

            var tokenFrom = configureContext.Parameters.GetOrDefault("token-from")?? "headers";
            var tokenKey = configureContext.Parameters.GetOrDefault("token-key")?? "authorization";
            var tokenFormat = configureContext.Parameters.GetOrDefault("token-format") ?? "Bearer {token}";
            //直接解析第三方token标识，有就走插件认证
            var thirdpartAuthorization = input.Context.Request.Headers.GetOrDefault(tokenKey).ToString() ?? "";

            if (thirdpartAuthorization.IsNullOrWhiteSpace())
            {
                return new VerifyOutput
                {
                    IsValid = false,
                };
            }

            var token = string.Empty;
            if("headers"==tokenFrom)
            {
                token = input.Context.Request.Headers.GetOrDefault(tokenKey).ToString();
            }
            else
            {
                token = input.Context.Request.Query[tokenKey].ToString();
                if(string.IsNullOrWhiteSpace(token))
                {
                    token = input.Context.Request.Form[tokenKey].ToString();
                }
            }

            var tokenTo = configureContext.Parameters.GetOrDefault("token-from") ?? "headers";
            var toTokenKey = configureContext.Parameters.GetOrDefault("to-token-key") ?? "authorization";

            if(token.IsNullOrWhiteSpace())
            {
                return new VerifyOutput
                {
                    IsValid = false,
                };
            }

            token = tokenFormat.Replace("{token}", token);

            var method = configureContext.Parameters.GetOrDefault("method")??"post";
            var url = $"{configureContext.Parameters.GetOrDefault("url")}?{toTokenKey}={token}";
            var httpClient = new HttpClient();

            string result = null;
            VerifyOutput output=null;
            try
            {
                if(tokenTo== "headers")
                {
                    httpClient.DefaultRequestHeaders.Add(toTokenKey, token);
                }
                if(method=="post")
                {
                    var resp = httpClient.PostAsync(url,null).Result;
                    result = resp.Content.ReadAsStringAsync().Result;
                    output= JsonConvert.DeserializeObject<VerifyOutput>(result);
                }
                else
                {
                    result = httpClient.GetStringAsync(url).Result;
                    output= JsonConvert.DeserializeObject<VerifyOutput>(result);
                }
                
            }
            catch (Exception ex)
            {
                Console.WriteLine($"DefaultCustomizationVerifyExtension:{url},{result}");
                output= new VerifyOutput { IsValid = false };
            }
            if(output.IsValid&&output.User!=null&&string.IsNullOrWhiteSpace(output.User.AppId))
            {
                output.User.AppId = input.AppId;
            }
            return output;
        }
    }
}
